package com.grad.webstudy.annota.resolver;

import com.grad.webstudy.annota.LoginAuthorization;
import com.grad.webstudy.constants.TokenConstants;
import com.grad.webstudy.context.UserContext;
import com.grad.webstudy.enums.ExceptionEnums;
import com.grad.webstudy.exceptions.CustomException;
import com.grad.webstudy.model.Token;
import com.grad.webstudy.service.TokenService;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Component;
import org.springframework.web.bind.MissingServletRequestParameterException;
import org.springframework.web.method.HandlerMethod;
import org.springframework.web.servlet.handler.HandlerInterceptorAdapter;

import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import java.lang.reflect.Method;

/**
 * @Description: 登录验证器，对需要登录的操作进行验证
 * @Author: zjf
 * @Date: 2020/1/19 16:55.
 */
@Component
public class LoginAuthorizationInterceptor extends HandlerInterceptorAdapter {

    @Autowired
    private TokenService tokenService;


    /**
     * 在请求执行前，验证用户是否登录
     * 登录验证通过放行，并在ThreadLocal中放入该用户的信息
     *
     * @param request
     * @param response
     * @param handler
     * @return
     * @throws MissingServletRequestParameterException
     */
    public boolean preHandle(HttpServletRequest request, HttpServletResponse response, Object handler) throws MissingServletRequestParameterException {

        if (!(handler instanceof HandlerMethod)) {
            return true;
        }
        HandlerMethod handlerMethod = (HandlerMethod) handler;
        Method method = handlerMethod.getMethod();
        //如果没有注解，直接放行
        if (method.getAnnotation(LoginAuthorization.class) == null) {
            return true;
        }
        String token = request.getHeader(TokenConstants.TOKEN);

        //token校验失败，抛出自定义异常
        if (!tokenService.checkToken(token)) {
            throw new CustomException(ExceptionEnums.TOKEN_INVALID.getCode(),
                    ExceptionEnums.TOKEN_INVALID.getMessage());

        }
        tokenService.refresh(token);
        Token tokenEntity = tokenService.getToken(token);
        UserContext.setLoginUser(tokenEntity.getUser());

        return true;

    }

    /**
     * 在一个请求执行后，从ThreadLocal删除用户信息，防止内存溢出
     *
     * @param request
     * @param response
     * @param handler
     * @param ex
     * @throws Exception
     */
    @Override
    public void afterCompletion(HttpServletRequest request, HttpServletResponse response, Object handler, Exception ex) throws Exception {


        if (!(handler instanceof HandlerMethod)) {
            return ;
        }
        HandlerMethod handlerMethod = (HandlerMethod) handler;
        Method method = handlerMethod.getMethod();
        //如果没有注解，直接放行
        if (method.getAnnotation(LoginAuthorization.class) == null) {
            return ;
        }

        System.out.println("清除用户信息");
        UserContext.removeLoginUser();
        System.out.println("清除完毕");
    }

}
